# encoding=utf-8

import logging
import asyncio

from .asynclib import (
    get_loop,
    create_task,
)
from .common import (
    async_cleanup,
    register_sigterm_handler,
    running,
)
from .db_data import yield_result
from .notifier import get_notifier

logger = logging.getLogger(__name__)


async def _handle_result(result_msg):
    try:
        notify_msgs = result_msg.pop("data_list", [])
        create_task(get_notifier(**result_msg).notify(notify_msgs=notify_msgs))
    except asyncio.CancelledError:
        raise
    except Exception as err:
        logger.exception('{!r}; failed to output result {}: {!s:.200}'.format(
            err, result_msg.job_id, result_msg,
        ))


async def arun():
    logger.debug('output event loop started')
    async for result_msg in yield_result():
        create_task(_handle_result(result_msg))
        if not running():
            break
    logger.debug('output event loop ended')


def run(name=None):
    # start worker in event loop
    logger.info('{} starting output event loop'.format(name))
    loop = get_loop()
    register_sigterm_handler(loop=loop, name=name)
    try:
        loop.run_until_complete(arun())
    except asyncio.CancelledError:
        logger.info('{} stopped'.format(name))
    except KeyboardInterrupt as err:
        logger.info('{!r}; {} got exit signal; exit'.format(err, name))
        loop.run_until_complete(async_cleanup(loop))
    logger.info('{} event loop ended'.format(name))
